package cn.edu.xmu.oomall.customer.dao;

import cn.edu.xmu.oomall.core.util.JacksonUtil;
import cn.edu.xmu.oomall.core.util.ReturnNo;
import cn.edu.xmu.oomall.core.util.ReturnObject;
import cn.edu.xmu.oomall.customer.mapper.CustomerPoMapper;
import cn.edu.xmu.oomall.customer.model.bo.Customer;
import cn.edu.xmu.oomall.customer.model.po.CustomerPo;
import cn.edu.xmu.oomall.customer.model.po.CustomerPoExample;
import cn.edu.xmu.privilegegateway.annotation.util.Common;
import cn.edu.xmu.privilegegateway.annotation.util.bloom.BloomFilter;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Repository;

import java.time.LocalDateTime;
import java.util.List;

@Repository
/**
 * @author Jiazhe Yuan
 * @date 2021-12-14 12:16:31
 */
public class NewCustomerDao implements InitializingBean {

    @Autowired(required = false)
    private CustomerPoMapper customerPoMapper;

    @Autowired
    BloomFilter<String> stringBloomFilter;

    final String EMAILFILTER="NewCustomerEmailBloomFilter";
    final String MOBILEFILTER="NewCustomerMobileBloomFilter";
    final String NAMEFILTER="NewCustomerNameBloomFilter";

    @Value("${customer.bloomfilter.new-user-email.error-rate}")
    private double emailError = 0.01;
    @Value("${customer.bloomfilter.new-user-email.capacity}")
    private int emailCapacity = 10000;

    @Value("${customer.bloomfilter.new-user-name.error-rate}")
    private double nameError = 0.01;
    @Value("${customer.bloomfilter.new-user-name.capacity}")
    private int nameCapacity = 10000;

    @Value("${customer.bloomfilter.new-user-mobile.error-rate}")
    private double mobileError = 0.01;
    @Value("${customer.bloomfilter.new-user-mobile.capacity}")
    private int mobileCapacity = 10000;

    @Override
    public void afterPropertiesSet() throws Exception {
        if (!stringBloomFilter.checkFilter(EMAILFILTER)) {
            stringBloomFilter.newFilter(EMAILFILTER, emailError, emailCapacity);
        }

        if (!stringBloomFilter.checkFilter(NAMEFILTER)) {
            stringBloomFilter.newFilter(NAMEFILTER, nameError, nameCapacity);
        }

        if (!stringBloomFilter.checkFilter(MOBILEFILTER)) {
            stringBloomFilter.newFilter(MOBILEFILTER, mobileError, mobileCapacity);
        }
    }

    public ReturnObject checkBloomFilter(CustomerPo po){
        if(stringBloomFilter.checkValue(EMAILFILTER, po.getEmail())){
            return new ReturnObject(ReturnNo.CUSTOMER_EMAILEXIST);
        }
        if(stringBloomFilter.checkValue(MOBILEFILTER, po.getMobile())){
            return new ReturnObject(ReturnNo.CUSTOMER_MOBILEEXIST);
        }
        if(stringBloomFilter.checkValue(NAMEFILTER, po.getUserName())){
            return new ReturnObject(ReturnNo.CUSTOMER_NAMEEXIST);
        }
        return null;
    }


    public ReturnObject createNewCustomerByBo(Customer customer) {
        CustomerPo customerPo = Common.cloneVo(customer, CustomerPo.class);
        List<CustomerPo> customerPos = null;
        ReturnObject returnObject = null;
        CustomerPoExample customerPoExample = new CustomerPoExample();
        try {
            CustomerPoExample.Criteria criteria_username = customerPoExample.createCriteria();
            criteria_username.andUserNameEqualTo(customerPo.getUserName());
            customerPos = customerPoMapper.selectByExample(customerPoExample);
            //System.out.println(JacksonUtil.toJson(customerPos));
            if (!customerPos.isEmpty()) {
                return new ReturnObject(ReturnNo.CUSTOMER_NAMEEXIST);
            }
        } catch (Exception e) {
            return new ReturnObject(ReturnNo.INTERNAL_SERVER_ERR);
        }

        try {
            customerPoExample.clear();
            CustomerPoExample.Criteria criteria_email = customerPoExample.createCriteria();
            criteria_email.andEmailEqualTo(customerPo.getEmail());
            customerPos = customerPoMapper.selectByExample(customerPoExample);
            //System.out.println(JacksonUtil.toJson(customerPos));
            if (!customerPos.isEmpty()) {
                return new ReturnObject(ReturnNo.CUSTOMER_EMAILEXIST);
            }
        } catch (Exception e) {
            return new ReturnObject(ReturnNo.INTERNAL_SERVER_ERR);
        }

        try {
            customerPoExample.clear();
            CustomerPoExample.Criteria criteria_mobile = customerPoExample.createCriteria();
            criteria_mobile.andMobileEqualTo(customerPo.getMobile());
            customerPos = customerPoMapper.selectByExample(customerPoExample);
            //System.out.println(JacksonUtil.toJson(customerPos));
            if (!customerPos.isEmpty()) {
                return new ReturnObject(ReturnNo.CUSTOMER_MOBILEEXIST);
            }
        } catch (Exception e) {
            return new ReturnObject(ReturnNo.INTERNAL_SERVER_ERR);
        }

        returnObject = checkBloomFilter(customerPo);
        if (null != returnObject) {
            return returnObject;
        }
        try {
            stringBloomFilter.addValue(NAMEFILTER,customer.getUserName());
            stringBloomFilter.addValue(EMAILFILTER,customer.getEmail());
            stringBloomFilter.addValue(MOBILEFILTER,customer.getMobile());
            customerPo.setGmtCreate(LocalDateTime.now());
            customerPoMapper.insert(customerPo);
            returnObject = new ReturnObject<>(customerPo);
        }
        catch (Exception e) {
            return new ReturnObject(ReturnNo.INTERNAL_SERVER_ERR);
        }
        return returnObject;
    }
}
